<?php

namespace App\Console\Commands;

use App\Services\MenuService;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Artisan;

class Install extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'b2b2c:install';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'b2b2c Install Command Start';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {

        // 判断是否解开禁用函数
        $disable_functions = ['shell_exec','exec','symlink','proc_open','putenv'];
        $disabled = false;
        for($i=0;$i<count($disable_functions);$i++){
            if(!function_exists($disable_functions[$i])){
                $disabled = true;
                break;
            }
        }

        if($disabled){
            $this->line('');
            $this->error('disabled_functions error. Please go php.ini Delete [shell_exec|exec|symlink|proc_open|putenv]...');
            $this->line('');
            return;
        }

        $domain = $this->anticipate('Please enter your Domain name (https://xxx.com)', ['http://127.0.0.1', 'localhost']);

        if(stripos($domain,'https://')===false && stripos($domain,'http://')===false){
            $this->error('Domain name error. Please fill in again...');
            return;
        }

        $mysqlHost = $this->anticipate('Please enter your MySQL address (Host)', ['127.0.0.1', 'localhost']);
        $dbPort = $this->anticipate('Please enter your MySQL port ', ['3306']);
        $dbName = $this->anticipate('Please enter your MySQL DBName ', ['b2b2c', 'shop']);
        $dbUserName = $this->anticipate('Please enter your MySQL DBusername ', ['root','b2b2c']);
        $dbPassword = $this->anticipate('Please enter your MySQL DBpassword ', ['root','b2b2c']);

        // 设置成功Mysql
        $this->table(['domain','host','prot','dbname','username','password'], [[$domain,$mysqlHost,$dbPort,$dbName,$dbUserName,$dbPassword]]);
        $this->line('');
        if(empty($domain) || empty($mysqlHost) || empty($dbPort) || empty($dbName) || empty($dbUserName)){
            return $this->error('Setting Error.');
        }

        // 开始修改.env 数据
        $this->modifyEnv([
            'APP_URL'       =>  $domain,
            'APP_DEBUG'     =>  'false',
            'DB_HOST'       =>  $mysqlHost,
            'DB_PORT'       =>  $dbPort,
            'DB_DATABASE'   =>  $dbName,
            'DB_USERNAME'   =>  $dbUserName,
            'DB_PASSWORD'   =>  $dbPassword,
        ]);

        $bar = $this->output->createProgressBar(11);

        // 创建模块配置表，创建数据库表
        $bar->advance();
        $this->line('');
        $this->line('');
        $this->line('Create module migration table. Please wait...');
        Artisan::call('goodcatch:table'); // 初始化模块
        $this->line('');
        $this->line('');
        $this->info('Created module migration table successfully.');
        // 执行数据库迁移之前清理配置
        $bar->advance();
        $this->line('');
        $this->line('');
        $this->line('Migrating table. Please wait...');
        Artisan::call('config:clear'); // 清空缓冲
        Artisan::call('config:cache'); // 继续缓冲
        Artisan::call('migrate');
        $this->info('Migrated table successfully.');
        // 导入数据
        $bar->advance();
        $this->line('');
        $this->line('');
        $this->line('Importing database data. Please wait...');
        Artisan::call('b2b2c:mysql');
        $this->line('');
        $this->line('');
        $this->info('Database data imported successfully.');
        // 创建 jwt_key
        $bar->advance();
        $this->line('');
        $this->line('');
        $this->line('Generate new JWT key. Please wait...');
        Artisan::call('jwt:secret');
        $this->line('');
        $this->line('');
        $this->info('Generated jwt secret key successfully.');
        // 生成 app_key
        $bar->advance();
        $this->line('');
        $this->line('');
        $this->line('Generate new app key. Please wait...');
        Artisan::call('key:generate');
        $this->line('');
        $this->line('');
        $this->info('Generated app key successfully.');
        // 清理模块配置准备安装模块
        $bar->advance();
        $this->line('');
        $this->line('');
        $this->line('Initiating modules. Please wait...');
        Artisan::call('goodcatch:cache'); // 重置模块缓存
        Artisan::call('config:clear'); // 清空缓冲
        Artisan::call('config:cache'); // 继续缓冲
        $this->line('');
        $this->line('');
        $this->info('Initiated modules successfully.');
        // 发布模块文件
        $bar->advance();
        $this->line('');
        $this->line('');
        $this->line('Publishing module resources. Please wait...');
        Artisan::call('vendor:publish', [
            '--tag' => 'laravel-modules',
            '--force' => true
        ]);
        $this->line('');
        $this->line('');
        $this->info('Published module resources successfully.');
        // 创建所有模块的表
        $bar->advance();
        $this->line('');
        $this->line('');
        $this->line('Migrating module table. Please wait...');
        Artisan::call('goodcatch:migrate'); // 发布模块文件
        $this->line('');
        $this->line('');
        $this->info('Migrated module table successfully.');
        // 导入模块数据
        $bar->advance();
        $this->line('');
        $this->line('');
        $this->line('Importing module data. Please wait...');
        Artisan::call('goodcatch:seed qwshop'); // 导入模块 qwshop 数据
        Artisan::call('goodcatch:seed core'); // 导入模块 core 数据
        $this->line('');
        $this->line('');
        $this->info('Import module data successfully.');
        // 重新清理配置
        $bar->advance();
        $this->line('');
        $this->line('');
        $this->line('Config Clear. Please wait...');
        Artisan::call('config:clear');
        Artisan::call('config:cache');
        $this->line('');
        $this->line('');
        $this->info('Cache configuration successfully.');

        // 清理菜单
        $menu_servcice = new MenuService;
        $menu_servcice->clearCache();

        // 创建软链接 storage
        $bar->advance();
        $this->line('');
        $this->line('');
        $this->line('Creating soft link storage. Please wait...');
        Artisan::call('storage:link');
        $this->line('');
        $this->line('');
        $this->info('Created soft link link storage successfully.');
        // 修改前端接口链接
        $bar->advance();
        $this->line('');
        $this->line('');
        $this->info('Update front end interface link. Please wait...');
        Artisan::call('b2b2c:vue '.$domain);
        $this->line('');
        $this->line('');
        $this->info('Updated front end interface link successfully.');

        $bar->finish();

        $this->line('');
        $this->line('');
        $this->info('Installed successfully , Welcome b2b2c.');
        $this->line('');
        $this->line('Admin url :  '.$domain.'/Admin/login');
        $this->line('Seller url :  '.$domain.'/Seller/login');
        $this->line('Admin username :  admin');
        $this->line('Admin password :  123456');
        $this->line('');
        $this->line('Run following commands if required for front end');
        $this->info('npm install');
        $this->info('npm run prod');
        return;

    }

    // 修改env
    function modifyEnv(array $data){
        $envPath = base_path()  . DIRECTORY_SEPARATOR . '.env';
        $contentArray = collect(file($envPath, FILE_IGNORE_NEW_LINES));

        $contentArray->transform(function ($item) use ($data){
            foreach ($data as $key => $value){
                if(str_contains($item, $key)){
                return $key . '=' . $value;
                }
            }
            return $item;
        });

        // 修改.env数据
        $content = implode(PHP_EOL,$contentArray->toArray());
        file_put_contents($envPath, $content);

    }
}
